#include <bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
int t;
int n, m;
long long L, V;
struct DATA {
    long long d, v, a;
    int l, r, det;
} car[maxn];
long double det[maxn];

int main() {
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> t;
    while(t--) {
        cin >> n >> m >> L >> V;
        for (int i = 1; i <= n; i++) {
            cin >> car[i].d >> car[i].v >> car[i].a;
        }
        for (int i = 1; i <= m; i++) cin >> det[i];
        for (int i = 1; i <= n; i++) {
            if (car[i].a == 0) {
                if (car[i].v > V) {
                    car[i].l = lower_bound(det + 1, det + m + 1, car[i].d * 1.0) - det;
                    car[i].r = m;
                    if (car[i].l <= m) car[i].det = true;
                    else car[i].det = false;
                } else {
                    car[i].det = false;
                }
            }
            else if (car[i].a > 0) {
                if (car[i].v > V) {
                    car[i].l = lower_bound(det + 1, det + m + 1, car[i].d * 1.0) - det;
                    car[i].r = m;
                    if (car[i].l <= m) car[i].det = true;
                    else car[i].det = false;
                } else {
                    long double tt = 1.0 * (V - car[i].v) / car[i].a;
                    long double dd = (car[i].v + V) * tt / 2 + car[i].d;
                    car[i].l = upper_bound(det + 1, det + m + 1, dd * 1.0) - det;
                    car[i].r = m;
                    if (car[i].l <= m) car[i].det = true;
                    else car[i].det = false;
                }
            }
            else if (car[i].a < 0) {
                if (car[i].v > V) {
                    long double tt = 1.0 * (V - car[i].v) / car[i].a;
                    long double dd = (car[i].v + V) * tt / 2 + car[i].d;
                    car[i].l = lower_bound(det + 1, det + m + 1, car[i].d * 1.0) - det;
                    car[i].r = lower_bound(det + 1, det + m + 1, dd * 1.0) - det - 1;
                    if (car[i].l > m) car[i].det = false;
                    else if (car[i].r == 0) car[i].det = false;
                    else if (car[i].l > car[i].r) car[i].det = false;
                    else car[i].det = true;
                } else {
                    car[i].det = false;
                }
            }
        }
        int detsum = 0, setsum = 0;
        for (int i = 1; i <= n; i++) detsum += car[i].det;
        cout << detsum << " ";
        auto cmp = [&](const DATA& a, const DATA& b) -> const bool {
            if (a.det == false) return false;
            if (b.det == false) return true;
            return a.l < b.l;
        };
        // pai chu det == 0 de qing kuang!!!!
        sort(car + 1, car + n + 1, cmp);
        int ptr = 1, minr = INT_MAX;
        // for (int i = 1; i <= n; i++) {
        //     printf("car#%d: %d %d %d\n", i, car[i].det, car[i].l, car[i].r);
        // }
        for (int i = 1; i <= m + 1; i++) {
            if (i > car[detsum].l) {
                setsum++;
                break;
            }
            if (i < car[ptr].l) continue;
            if (i > minr) {
                setsum++;
                //cout << endl;
                minr = car[ptr].r;
            }
            int ptr2 = ptr;
            while (car[ptr2].l == car[ptr].l && ptr2 <= detsum) {
                minr = min(minr, car[ptr2].r);
                //cout << ptr2 << ' ';
                ptr2++;
            }
            ptr = ptr2;
        }
        cout << m - setsum << endl;
    }
}